#include "Aimbot.h"
#include "HL2Interface.h"
#include "NoSpread.h"

Aimbot g_pAimbot;

SD_Tools::Vector GetEyePosition(Entity* pEntity)
{
	SD_Tools::Vector absOrigin	   = *pEntity->vecOrigin();
	SD_Tools::Vector vecViewOffset = *pEntity->vecViewOffset();
	return SD_Tools::MathHelper::AddVector(absOrigin, vecViewOffset);
}

void Aimbot::DropTarget()
{
	vFinal	   = SD_Tools::Vector();
	m_iTarget  = -1;
	m_flDistance = 999999999.9f;
}

float Aimbot::GetDistance(SD_Tools::Vector &src, SD_Tools::Vector &dst)
{
	float x = src.x - dst.x;
	float y = src.y - dst.y;
	float z = src.z - dst.z;
	float d = sqrt(x * x + y * y + z * z);
	return d;
}

void Aimbot::AimAtTarget(CUserCmd* cmd)
{
	DropTarget();
	player_info_t pinfo;
	SD_Tools::Vector vPlayer;

	Entity* pMe = g_pInterfaces.g_pEntList->GetClientEntity(g_pInterfaces.g_pEngine->GetLocalPlayer());
	SD_Tools::Vector m_Eye = GetEyePosition(pMe);

	int iClients = g_pInterfaces.g_pEngine->GetMaxClients();
	for(int index = 1; index <= iClients; ++index)
	{
		Entity* baseEntity = g_pInterfaces.g_pEntList->GetClientEntity(index);
		if(baseEntity == NULL || *baseEntity->dormant() || baseEntity == pMe || *baseEntity->lifeState() != 0 /*LIFE_ALIVE*/ || !g_pInterfaces.g_pEngine->GetPlayerInfo(index, &pinfo) 
			|| *baseEntity->iTeamNum() == *pMe->iTeamNum() || !baseEntity->GetBone(BONE_HEAD, &vPlayer) || !IsVisible(m_Eye, vPlayer, pMe, baseEntity))
			continue;
		float m_Dist = GetDistance(m_Eye, vPlayer);
		if(m_flDistance < m_Dist)
			continue;
		m_flDistance =  m_Dist;
		m_iTarget = index;
		baseEntity->GetBone(BONE_HEAD, &vFinal);
		vFinal.z += 4.f;
		continue;
	}
	if(m_iTarget == -1)
		return;
	cmd->buttons |= IN_ATTACK;
	cmd->viewangles = CreateAimAngle(m_Eye, vFinal);
	g_pInterfaces.g_pEngine->SetViewAngles(cmd->viewangles);
}

void Aimbot::Triggerbot(CUserCmd* cmd)
{
	SD_Tools::Vector vMin,vMax,vecPosition,vPlayer, Origin;
	SD_Tools::Angle angles, spread, fTraceVec;
	Entity* pMe = g_pInterfaces.g_pEntList->GetClientEntity(g_pInterfaces.g_pEngine->GetLocalPlayer());

	if(!pMe)
		return;

	SD_Tools::Vector m_Eye = GetEyePosition(pMe);
	trace_t tr;
	Ray_t ray;

	//player_info_t pInfo;

	fTraceVec = cmd->viewangles;	

	g_pNoSpread.GetSpreadFix(cmd->random_seed, cmd->viewangles, spread);

	fTraceVec.Subtract(spread);	

	SD_Tools::Vector punch = *pMe->getRecoilVec();

	fTraceVec.x += punch.x;
	fTraceVec.y += punch.y;
	fTraceVec.z  = 0.f;

	fTraceVec.ToVectors_s(0, 0, &Origin);

	Origin.Multiply(8192.0f);
	Origin.Add(m_Eye);

	ray.Init(m_Eye, Origin);

	g_pInterfaces.g_pEngineTrace->TraceRay( ray, MASK_NPCWORLDSTATIC|CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX, NULL, &tr );

	Entity* bEnt = tr.m_pEnt;
	if(bEnt && (*bEnt->iTeamNum() != *pMe->iTeamNum()) && !*bEnt->dormant() && (*bEnt->lifeState()) == 0)
	{
		cmd->buttons |= IN_ATTACK;
		return;
	}
}